Date		:	6 d�cembre 1991
		Protection	:	MOT DE PASSE
		Programme	:       MIGHT and MAGIC III
		Outils		:	SOFT-ICE V2.50
		Fichier		:	MM3.EXE
		Temps pass�	:	3 heures
		Soci�t�		:	NEW WORLD COMPUTING
		Divers	        :	Confection d'un lanceur COM.
		Origine		:	B.Y.
		Num�ro		:	154


	Un examen du fichier EXE avant toute chose me montre qu'il est compact�
	par une m�thode non publique. Avant m�me de trouver la protection cela
	indique qu'il faudra utiliser un lanceur pour d�jouer la demande du
	mot de passe. Mais avant toute chose il faut d'abord trouver la
	protection. Je nage pendant un bout de temps avant de me d�cider �
	utiliser la solution ultime qui consiste � comparer un programme se
	d�roulant en ayant tap� un code correct avec un programme dans lequel
	j'ai juste appuy� sur la touche ENTER.
	Les deux programmes se d�roulent de la m�me fa�on jusqu'� un CALL 153
	duquel on revient par un RETF ! Et la position du retour SS:SP est
	bien entendu diff�rente suivant que l'on a tap� le bon ou le mauvais
	code. Smart isn'it ?.
	J'ex�cute ce CALL au pas � pas au moins une demi-douzaine de fois avant
	de comprendre de quelle mani�re je me retrouve avec des vecteurs de
	retour diff�rent dans un cas et dans l'autre. Cette routine est bien
	celle qui teste les caract�res tap�s lors de la demande du code.
	Elle est appel�e en 9CCA:0008 par un CALL 0153 et appara�t ci-dessous
	compl�te:

		SUB	AX,AX
		SUB	SI,+0D
		AND	BX,EFDF
		MOV	DS,DX
		MOV	DX,7F60
		MOV	CL,20
	0163:	LODSB          <�ͻ 	; Cha�ne des caract�res tap�s DS:SI
		AND	AL,DH     �
  �����������	JZ	01A8      �     ; Si z�ro ( fin de cha�ne ) 01A8
  �		CMP	AL,CL     �
  �����������  	JZ	01A8      �
  �		CMP	AL,DL     �
  �		JB	0172   ͻ �
  �		SUB	AL,CL   � �
  �	0172:	ROR	BL,1  <ͼ �
  �		XCHG	BL,BH     �
  �		ROR	BX,1      �
  �		ADD	BX,AX     �
  �		JMP	0163	�ͼ
  � ��> 017C:	POP	BX
  � �		POP	SI
  � �		POP	DS
  � �	017F:	INC	SI    <������������ͻ
  � �	0180:	CMP	WORD PTR [SI],5374  � <�ͻ
  � �		JNZ	017F  �������������ͼ    �
  � �		INC	SI                       �
  � �		INC	SI                       �
  � �		CMP	WORD PTR [SI],6570       �
  � �		JNZ	0180  ������������������ͼ
  � �		INC	SI
  � �		INC	SI
  � �		PUSH	DS
  � �		MOV	CX,0027
  � �	0194:	XOR	[SI],CL <�ͻ
  � �		INC	SI         �
  � �		LOOP	0194  ����ͼ
  � �		ADD	DI,0403
  � �		XOR	DX,08E2
  � �		PUSH	DI
  � �		PUSH	BX
  � �		MOV	CX,F001
  � �		JNZ	01B5  ����ͻ
  �����>01A8:	MOV	SI,001E    �
    �		POP	AX         �
    � 		POP	CX         �
    �		POP	DS         �
    �	01AE:	LODSW        <�ͻ  �
    �		CMP	AX,BX   �  �
    ����01B1:	JZ	017C    �  �	; adr_IP = 01B1, � modifier par JMP.
		LOOP	01AE  �ͼ  �
	01B5:	ADD	CX,0FFF <�ͼ  
		POP	DS
		RETF

	Lorsque l'on tape juste ENTER le programme saute directement en 1A8
	puis boucle dans LOOP 1AE. Dans ce dernier cas il ne trouve jamais
	d'�galit� et lorsque CX = 0 il sort par le RETF avec des valeurs de
	SS:SP ne correspondant pas � la suite normale du programme:
	1473:058C apr�s l'ex�cution du RETF. 
	Dans le cas d'une bonne r�ponse il passe par 017C et en examinant la
	suite du code on s'aper�oit que l'on fait deux PUSH DI et DX avant de
	faire un RETF. DI doit contenir 058C pour que tout se passe bien.
	D�s lors il ne suffit plus que de modifier le test en 01B1 en saut
	inconditionnel. Et voil�.

	Ci dessous le listing.asm qui comporte deux nouveaut�s:

     1) Toutes les r�f�rences au programme fils ainsi que la fen�tre
	d'affichage de FREDDY_SOFT sont XOR� par un XOR variable appliqu� sur
	une zone d�limit�e par des A5A5. Cette zone pouvant �tre
	indiff�rement du code ou des donn�es.
	La fen�tre n'est affich�e que si une carte VGA est d�tect�e. En EGA
	la protection est enlev�e mais aucun message n'apparait.
     2) Une autre "am�lioration" consiste � remettre en place imm�diatement
	apr�s l'action du patch, le vecteur d'origine de l'interruption
	d�tourn�e. Impossible d'utiliser la fonction 25h de l'INT21h puisque le
	DOS n'est pas r�entrant. Cela aurait fonctionn� pour les autres
	interruptions mais pas la 21h.

;       PATCH POUR LE PROGRAMME MIGHT and MAGIC III
;       DETOURNEMENT DE L'INT 21 SOUS-FONCTION 42
;
;******************************************************************************
;                             ZONE A INITIALISER

adr_ip1         equ     01b1h   ; adresse dont le contenu est � modifier.
anc_val         equ     0c974h  ; Valeur d'origine � rechercher.
nouv_val        equ     0c9ebh  ; Nouvelle valeur. 
INT_DET         equ     21h     ; Le num�ro de l'INT que l'on veut utiliser.
sous_fonction   equ     42h     ; Sous-fonction utilis�e.

;******************************************************************************

seg_a           segment byte public

		assume  cs:seg_a, ds:seg_a, es:seg_a, ss:seg_a
  
		org     100h

sto             proc    far

start:
		jmp     init            ; r�duire la m�moire et d�placer la 
		db      90h             ; pile plus pr�s.
paramet         dw      0               ; M�me bloc d'environnement.            
ENVIR           dw      0               ; Les param�tres de la ligne de 
data_3          dw      0               ; commande sont recopi�s ici puis
FCB_1           dw      0               ; transmis au programme fils. ( 80h )
data_5          dw      0               
FCB_2           dw      0
data_7          dw      0
sauve_SP        dw      0
sauve_SS        dw      0
data_9          dw      0, 0
drap            equ     0

;------------------------------ PROGRAMME PERE ------------------------------

loc_1:          mov     sauve_SP,sp
		mov     sauve_SS,ss
		mov     ax,80h
		mov     ENVIR,ax        ; Ligne de commande...
		mov     data_3,ds
		mov     ax,5Ch          ; Premier FCB ( inutilis� )
		mov     FCB_1,ax
		mov     data_5,ds
		mov     ax,6Ch          ; Second FCB ( inutilis� )
		mov     FCB_2,ax
		mov     data_7,ds
		mov     ah,35h  
		mov     al,INT_DET
		int     21h             ; DOS Services  ah=function 35h
					;  get intrpt vector al in es:bx
		mov     cs:data_9,bx
		mov     word ptr cs:data_9+2,es
		mov     ah,25h          
		mov     al,INT_DET              
		lea     dx,cs:[_int]    ; Load effective addr
		int     21h             ; DOS Services  ah=function 25h
					;  set intrpt vector al to ds:dx
		lea     dx,cs:[nom_prg] ; Load effective addr
		push    ds
		pop     es
		lea     bx,cs:[paramet] ; Load effective addr
		mov     al,0
		mov     ah,4Bh          
		int     21h             ; Appel du programme fils.
					; run progm @ds:dx, parm @es:bx
		mov     sp,sauve_SP     
		mov     ss,sauve_SS     
		cmp     al,2            ; teste le code de retour du programme
		jnz     ok              ; fils, 02 si pas trouv�.
		mov     dx,offset mess_err      
		mov     ah,9
		int     21h

	; Les cinq instructions suivantes sont facultatives puisque le
	; vecteur d'origine est remis en place d�s que le patch est effectu�.
	; Le seul but est d'�viter le plantage du PC dans l'hypoth�se o� l'on
	; lance le programme p�re et que celui-ci ne trouve pas le programme
	; fils. A ce moment l� on remet tout en place et on quitte.

ok:             mov     ah,25h
		mov     al,INT_DET
		mov     dx,cs:data_9
		mov     ds,word ptr cs:data_9+2
		int     21h             

		mov     ah,4Ch
		int     21h             ;  terminate with al=return code
sto             endp

;---------------------------- int d�tourn�e --------------------------------

int_entry       proc    far
_int:           push    ax
		push    ds
		push    bx
		pushf                           ; Push flags
		cmp     ah,sous_fonction        ; Sous - fonction de l'INT.
		jne     loc_2                   ; Jump if not equal
		mov     ax,sp
		add     sp,+34
		pop     ds                      
		cmp     word ptr ds:[adr_ip1],anc_val   ; Si ok on patche.
		jnz     s
		mov     word ptr ds:[adr_ip1],nouv_val  ; On y place le patch.
		xor     bx,bx
		mov     ds,bx                   

	; L'INT 21 n'est pas r�entrante, on ne peut donc pas se servir de
	; la fonction 25h ( set int. vector )   
	
		mov     bx,word ptr cs:data_9      ; Je remets manuellement
		mov     ds:[INT_DET*4],bx          ; en place le vecteur
		mov     bx,word ptr cs:data_9+2    ; de l'INT d�tourn�e.
		mov     ds:[INT_DET*4+2],bx        
s:              mov     sp,ax
loc_2:          popf    
		pop     bx
		pop     ds                      
		pop     ax
		jmp     dword ptr cs:data_9

int_entry       endp

;------------ REDUCTION DE LA PLACE OCCUPEE PAR LE PROGRAMME COM ------------

init:                                   ; D�codage du texte.
		cld                     ; Pour incr�menter SI et DI.
		xor ax,ax
		mov si,offset chaine    ; pointe sur le d�but de la chaine.
		mov di,si               ; DI �galement.

		mov cx,offset chaine_fin - offset chaine

					; 28 lignes de 6 caract�res sont XOR�s.
					; + mess_err ( 30 ) + nom_prog ( 13 ).
toto:           lodsb                   ; On cherche...
		xor al,ah               ; On XOR.
		stosb                   ; On remet.
		xchg ah,al
		loop toto               ; Et on tourne tant que CX # 0.

		mov ax,1a00h		; Test si carte + moniteur VGA
		int 10h
		cmp al,1ah
		je  graf 	    ; Si oui on affiche la fen�tre FREDDY_SOFT.
suite1:         mov ah,4ah              
		mov bx,offset fin   ; Fin du programme en BX.
		mov cl,4            ; Divis� par 4 pour avoir des paragraphes.  
		shr bx,cl
		inc bx              ; On en rajoute un par s�curit�.    
		int 21h             ; Execution de la fonction 4Ah.
		mov sp,offset fin   ; on d�place la pile en "fin" car elle est
		jmp loc_1           ; plac�e en FFFE dans un programme COM.

graf:           xor ah,ah       ; Raz de l'�cran
		mov al,3
		int 10h
		mov ax,1301h        ; Mode 01 attribut couleur dans BL. 
		mov bx,004bh        ; Page 0.
		mov cx,28           ; nombre de char.
		mov dx,0a19h        ; ligne,colonne.
		lea bp,cs:[chaine]
ligne_suiv:     int 10h
		inc dh
		add bp,28
		cmp dh,10h              ; 6 lignes de 28 caract�res.
		jb ligne_suiv 
		mov ah,2                ; Pour faire disparaitre le curseur.
		xor bh,bh               ; Page ecran 0.
		mov dh,25
		int 10h
		jmp suite1
		db	55h,0aah	; Identificateur de d�but.
chaine:         db      '��������FREDDY_SOFT!������Ŀ'
		db      '�                          �'
		db      '� MIGHT & MAGIC ]I[ Bypass �'
		db      "�  I hope you'll enjoy it  �"
		db      '�                          �'
		db      '�����������ETOYOC�����������'
mess_err        db      0ah,0dh,'Programme enfant non trouv�','$'
nom_prg         db      'mm3.exe',0,0,0,0,0,0   ; 12 car max + nul
chaine_fin:	db	0aah,55h	; Identificateur de fin.
fin_init        label near

;----------------------- PLACE RESERVEE POUR LA PILE ------------------------

		dw 100 dup (' ')
fin             equ this byte       ; ici le sommet de la pile, SP.
seg_a           ends
		end     start

	FREDDY